voicemeeter\interface\callback\data/
buffer_abstraction.rs

1//! Abstraction for each device.
2
3use self::sealed::{Buffer, BufferMut};
4use super::BufferDataExt;
5use super::Device;
6use super::{Input, Main, Output};
7
8pub(crate) mod sealed {
9    pub trait Buffer<'a, 'b>
10    where
11        'b: 'a,
12    {
13        fn as_slice(&'a self) -> &'a [&'b [f32]];
14        fn len(&'a self) -> usize {
15            self.as_slice().len()
16        }
17    }
18    pub trait BufferMut<'a, 'b>
19    where
20        'b: 'a,
21    {
22        fn as_mut_slice(&mut self) -> &mut [&'b mut [f32]];
23        fn len(&'a self) -> usize;
24    }
25}
26
27impl<'a, 'b: 'a, const N: usize> Buffer<'a, 'b> for [&'b [f32]; N] {
28    fn as_slice(&'a self) -> &'a [&'b [f32]] {
29        self
30    }
31
32    fn len(&'a self) -> usize {
33        N
34    }
35}
36
37impl<'a, 'b: 'a> Buffer<'a, 'b> for &'a [&'b [f32]] {
38    fn as_slice(&'a self) -> &'a [&'b [f32]] {
39        self
40    }
41}
42
43impl<'a, 'b: 'a, const N: usize> BufferMut<'a, 'b> for [&'b mut [f32]; N] {
44    fn as_mut_slice(&mut self) -> &mut [&'b mut [f32]] {
45        self
46    }
47
48    fn len(&'a self) -> usize {
49        N
50    }
51}
52
53impl<'a, 'b: 'a> BufferMut<'a, 'b> for &'a mut [&'b mut [f32]] {
54    fn as_mut_slice(&mut self) -> &mut [&'b mut [f32]] {
55        self
56    }
57    fn len(&'a self) -> usize {
58        self.as_ref().len()
59    }
60}
61
62/// A devices buffer.
63///
64/// See [`BufferMainData`](crate::interface::callback::BufferMainData), [`BufferInData`](crate::interface::callback::BufferInData) and [`BufferOutData`](crate::interface::callback::BufferOutData) for examples.
65#[derive(Default)]
66pub enum DeviceBuffer<T> {
67    /// Device does not exist
68    #[default]
69    None,
70    /// Device buffer
71    Buffer(T),
72}
73
74impl<T> DeviceBuffer<T> {
75    /// Converts from `&DeviceBuffer<T>` to `Option<&T>`.
76    pub fn as_opt_ref(&self) -> Option<&T> {
77        match self {
78            Self::None => None,
79            Self::Buffer(t) => Some(t),
80        }
81    }
82
83    /// Converts from `&mut DeviceBuffer<T>` to `Option<&mut T>`.
84    pub fn as_opt_mut(&mut self) -> Option<&mut T> {
85        match self {
86            Self::None => None,
87            Self::Buffer(t) => Some(t),
88        }
89    }
90
91    /// Converts from `&DeviceBuffer<T>` to `DeviceBuffer<&T>`.
92    pub fn as_ref(&self) -> DeviceBuffer<&T> {
93        match self {
94            Self::None => DeviceBuffer::None,
95            Self::Buffer(t) => DeviceBuffer::Buffer(t),
96        }
97    }
98
99    /// Converts from `&mut DeviceBuffer<T>` to `DeviceBuffer<&mut T>`.
100    pub fn as_mut(&mut self) -> DeviceBuffer<&mut T> {
101        match self {
102            Self::None => DeviceBuffer::None,
103            Self::Buffer(t) => DeviceBuffer::Buffer(t),
104        }
105    }
106
107    /// Returns `true` if the device buffer is [`None`].
108    ///
109    /// [`None`]: DeviceBuffer::None
110    pub fn is_none(&self) -> bool {
111        matches!(self, Self::None)
112    }
113
114    /// Returns `true` if the device buffer is [`Buffer`].
115    ///
116    /// [`Buffer`]: DeviceBuffer::Buffer
117    pub fn is_buffer(&self) -> bool {
118        matches!(self, Self::Buffer(..))
119    }
120}
121
122// mutable buffer impls
123impl<'a, 'b: 'a, B> DeviceBuffer<B>
124where
125    B: BufferMut<'a, 'b>,
126{
127    /// Make the buffer into a mutable slice
128    pub fn to_mut_slice(&'a mut self) -> &'a mut [&'b mut [f32]] {
129        match self {
130            Self::None => &mut [],
131            Self::Buffer(b) => b.as_mut_slice(),
132        }
133    }
134
135    /// Get the buffer as a mutable slice
136    pub fn as_mut_slice(&mut self) -> DeviceBuffer<&mut [&'b mut [f32]]> {
137        match self {
138            Self::None => DeviceBuffer::None,
139            Self::Buffer(b) => DeviceBuffer::Buffer(b.as_mut_slice()),
140        }
141    }
142    /// Given a device, apply a specific function on all channels
143    ///
144    /// The function is given the current channel as the first argument,
145    /// the samples in the read buffer as the second argument, and the write buffer as the third argument.
146    pub fn apply<F, B2: Buffer<'a, 'b>>(&'a mut self, read: &'a DeviceBuffer<B2>, mut f: F)
147    where
148        F: FnMut(usize, &[f32], &mut [f32]),
149    {
150        // FIXME: Assert that the sizes are equal for optimization
151        for (channel, (read, write)) in read
152            .to_slice()
153            .iter()
154            .zip(self.to_mut_slice().iter_mut())
155            .enumerate()
156        {
157            f(channel, read, write);
158        }
159    }
160
161    /// Given a device, apply a specific function on all channels and their samples.
162    ///
163    /// The function is given the current channel as the first argument,
164    /// the current sample in the read buffer as the second argument, and the current sample in the write buffer as the third argument.
165    pub fn apply_all_samples<F, B2: Buffer<'a, 'b>>(
166        &'a mut self,
167        read: &'a DeviceBuffer<B2>,
168        mut f: F,
169    ) where
170        F: FnMut(usize, &f32, &mut f32),
171    {
172        // FIXME: Assert that the sizes are equal for optimization
173        for (channel, (read, write)) in read
174            .to_slice()
175            .iter()
176            .zip(self.to_mut_slice().iter_mut())
177            .enumerate()
178        {
179            for (i, sample) in write.iter_mut().enumerate() {
180                f(channel, &read[i], sample);
181            }
182        }
183    }
184}
185
186impl<'a, 'b: 'a, B> DeviceBuffer<B>
187where
188    B: Buffer<'a, 'b>,
189{
190    /// Make the buffer into a slice
191    pub fn to_slice(&'a self) -> &'a [&'b [f32]] {
192        match self {
193            Self::None => &mut [],
194            Self::Buffer(b) => b.as_slice(),
195        }
196    }
197
198    /// Get the buffer as a mutable slice
199    pub fn as_slice(&'a self) -> DeviceBuffer<&'a [&'b [f32]]> {
200        match self {
201            Self::None => DeviceBuffer::None,
202            Self::Buffer(b) => DeviceBuffer::Buffer(b.as_slice()),
203        }
204    }
205}
206
207/// Main mode
208pub mod main {
209    use super::*;
210
211    /// Read interface for main mode
212    #[derive(Default)]
213    pub struct ReadDevices<'a, 'b> {
214        /// Channel read buffer for [`Strip1`](Device::Strip1).
215        ///
216        /// Is [`None`](DeviceBuffer::None) if the device is not available.
217        pub strip1: DeviceBuffer<[&'b [f32]; 2]>,
218        /// Channel read buffer for [`Strip2`](Device::Strip2).
219        ///
220        /// Is [`None`](DeviceBuffer::None) if the device is not available.
221        pub strip2: DeviceBuffer<[&'b [f32]; 2]>,
222        /// Channel read buffer for [`Strip3`](Device::Strip3).
223        ///
224        /// Is [`None`](DeviceBuffer::None) if the device is not available.
225        pub strip3: DeviceBuffer<[&'b [f32]; 2]>,
226        /// Channel read buffer for [`Strip4`](Device::Strip4).
227        ///
228        /// Is [`None`](DeviceBuffer::None) if the device is not available.
229        pub strip4: DeviceBuffer<[&'b [f32]; 2]>,
230        /// Channel read buffer for [`Strip5`](Device::Strip5).
231        ///
232        /// Is [`None`](DeviceBuffer::None) if the device is not available.
233        pub strip5: DeviceBuffer<[&'b [f32]; 2]>,
234        /// Channel read buffer for [`OutputA1`](Device::OutputA1).
235        ///
236        /// Is [`None`](DeviceBuffer::None) if the device is not available.
237        pub output_a1: DeviceBuffer<[&'b [f32]; 8]>,
238        /// Channel read buffer for [`OutputA2`](Device::OutputA2).
239        ///
240        /// Is [`None`](DeviceBuffer::None) if the device is not available.
241        pub output_a2: DeviceBuffer<[&'b [f32]; 8]>,
242        /// Channel read buffer for [`OutputA3`](Device::OutputA3).
243        ///
244        /// Is [`None`](DeviceBuffer::None) if the device is not available.
245        pub output_a3: DeviceBuffer<[&'b [f32]; 8]>,
246        /// Channel read buffer for [`OutputA4`](Device::OutputA4).
247        ///
248        /// Is [`None`](DeviceBuffer::None) if the device is not available.
249        pub output_a4: DeviceBuffer<[&'b [f32]; 8]>,
250        /// Channel read buffer for [`OutputA5`](Device::OutputA5).
251        ///
252        /// Is [`None`](DeviceBuffer::None) if the device is not available.
253        pub output_a5: DeviceBuffer<[&'b [f32]; 8]>,
254        /// Channel read buffer for [`VirtualOutputB1`](Device::VirtualOutputB1).
255        ///
256        /// Is [`None`](DeviceBuffer::None) if the device is not available.
257        pub virtual_output_b1: DeviceBuffer<[&'b [f32]; 8]>,
258        /// Channel read buffer for [`VirtualOutputB2`](Device::VirtualOutputB2).
259        ///
260        /// Is [`None`](DeviceBuffer::None) if the device is not available.
261        pub virtual_output_b2: DeviceBuffer<[&'b [f32]; 8]>,
262        /// Channel read buffer for [`VirtualOutputB3`](Device::VirtualOutputB3).
263        ///
264        /// Is [`None`](DeviceBuffer::None) if the device is not available.
265        pub virtual_output_b3: DeviceBuffer<[&'b [f32]; 8]>,
266        /// Channel read buffer for [`VirtualInput`](Device::VirtualInput).
267        ///
268        /// Is [`None`](DeviceBuffer::None) if the device is not available.
269        pub virtual_input: DeviceBuffer<[&'b [f32]; 8]>,
270        /// Channel read buffer for [`VirtualInputAux`](Device::VirtualInputAux).
271        ///
272        /// Is [`None`](DeviceBuffer::None) if the device is not available.
273        pub virtual_input_aux: DeviceBuffer<[&'b [f32]; 8]>,
274        /// Channel read buffer for [`VirtualInput8`](Device::VirtualInput8).
275        ///
276        /// Is [`None`](DeviceBuffer::None) if the device is not available.
277        pub virtual_input8: DeviceBuffer<[&'b [f32]; 8]>,
278        _pd: std::marker::PhantomData<&'a ()>,
279    }
280    impl<'a, 'b> ReadDevices<'a, 'b> {
281        /// Create a new buffer for this mode
282        pub(crate) unsafe fn new(buffer: &'_ mut Main) -> Self {
283            unsafe {
284                Self {
285                    strip1: buffer.device_read(&Device::Strip1),
286                    strip2: buffer.device_read(&Device::Strip2),
287                    strip3: buffer.device_read(&Device::Strip3),
288                    strip4: buffer.device_read(&Device::Strip4),
289                    strip5: buffer.device_read(&Device::Strip5),
290                    output_a1: buffer.device_read(&Device::OutputA1),
291                    output_a2: buffer.device_read(&Device::OutputA2),
292                    output_a3: buffer.device_read(&Device::OutputA3),
293                    output_a4: buffer.device_read(&Device::OutputA4),
294                    output_a5: buffer.device_read(&Device::OutputA5),
295                    virtual_output_b1: buffer.device_read(&Device::VirtualOutputB1),
296                    virtual_output_b2: buffer.device_read(&Device::VirtualOutputB2),
297                    virtual_output_b3: buffer.device_read(&Device::VirtualOutputB3),
298                    virtual_input: buffer.device_read(&Device::VirtualInput),
299                    virtual_input_aux: buffer.device_read(&Device::VirtualInputAux),
300                    virtual_input8: buffer.device_read(&Device::VirtualInput8),
301                    _pd: Default::default(),
302                }
303            }
304        }
305        /// Grab the device buffer for a specific device
306        pub fn device(&'a self, device: &Device) -> DeviceBuffer<&'a [&'b [f32]]> {
307            match device {
308                Device::Strip1 => self.strip1.as_slice(),
309                Device::Strip2 => self.strip2.as_slice(),
310                Device::Strip3 => self.strip3.as_slice(),
311                Device::Strip4 => self.strip4.as_slice(),
312                Device::Strip5 => self.strip5.as_slice(),
313                Device::OutputA1 => self.output_a1.as_slice(),
314                Device::OutputA2 => self.output_a2.as_slice(),
315                Device::OutputA3 => self.output_a3.as_slice(),
316                Device::OutputA4 => self.output_a4.as_slice(),
317                Device::OutputA5 => self.output_a5.as_slice(),
318                Device::VirtualOutputB1 => self.virtual_output_b1.as_slice(),
319                Device::VirtualOutputB2 => self.virtual_output_b2.as_slice(),
320                Device::VirtualOutputB3 => self.virtual_output_b3.as_slice(),
321                Device::VirtualInput => self.virtual_input.as_slice(),
322                Device::VirtualInputAux => self.virtual_input_aux.as_slice(),
323                Device::VirtualInput8 => self.virtual_input8.as_slice(),
324            }
325        }
326    }
327
328    /// Write interface for main mode
329    #[derive(Default)]
330    pub struct WriteDevices<'a, 'b> {
331        /// Channel write buffer for [`OutputA1`](Device::OutputA1).
332        ///
333        /// Is [`None`](DeviceBuffer::None) if the device is not available.
334        pub output_a1: DeviceBuffer<[&'b mut [f32]; 8]>,
335        /// Channel write buffer for [`OutputA2`](Device::OutputA2).
336        ///
337        /// Is [`None`](DeviceBuffer::None) if the device is not available.
338        pub output_a2: DeviceBuffer<[&'b mut [f32]; 8]>,
339        /// Channel write buffer for [`OutputA3`](Device::OutputA3).
340        ///
341        /// Is [`None`](DeviceBuffer::None) if the device is not available.
342        pub output_a3: DeviceBuffer<[&'b mut [f32]; 8]>,
343        /// Channel write buffer for [`OutputA4`](Device::OutputA4).
344        ///
345        /// Is [`None`](DeviceBuffer::None) if the device is not available.
346        pub output_a4: DeviceBuffer<[&'b mut [f32]; 8]>,
347        /// Channel write buffer for [`OutputA5`](Device::OutputA5).
348        ///
349        /// Is [`None`](DeviceBuffer::None) if the device is not available.
350        pub output_a5: DeviceBuffer<[&'b mut [f32]; 8]>,
351        /// Channel write buffer for [`VirtualOutputB1`](Device::VirtualOutputB1).
352        ///
353        /// Is [`None`](DeviceBuffer::None) if the device is not available.
354        pub virtual_output_b1: DeviceBuffer<[&'b mut [f32]; 8]>,
355        /// Channel write buffer for [`VirtualOutputB2`](Device::VirtualOutputB2).
356        ///
357        /// Is [`None`](DeviceBuffer::None) if the device is not available.
358        pub virtual_output_b2: DeviceBuffer<[&'b mut [f32]; 8]>,
359        /// Channel write buffer for [`VirtualOutputB3`](Device::VirtualOutputB3).
360        ///
361        /// Is [`None`](DeviceBuffer::None) if the device is not available.
362        pub virtual_output_b3: DeviceBuffer<[&'b mut [f32]; 8]>,
363        _pd: std::marker::PhantomData<&'a ()>,
364    }
365    impl<'a, 'b> WriteDevices<'a, 'b> {
366        /// Create a new buffer for this mode
367        pub(crate) unsafe fn new(buffer: &'_ mut Main) -> Self {
368            unsafe {
369                Self {
370                    output_a1: buffer.device_write(&Device::OutputA1),
371                    output_a2: buffer.device_write(&Device::OutputA2),
372                    output_a3: buffer.device_write(&Device::OutputA3),
373                    output_a4: buffer.device_write(&Device::OutputA4),
374                    output_a5: buffer.device_write(&Device::OutputA5),
375                    virtual_output_b1: buffer.device_write(&Device::VirtualOutputB1),
376                    virtual_output_b2: buffer.device_write(&Device::VirtualOutputB2),
377                    virtual_output_b3: buffer.device_write(&Device::VirtualOutputB3),
378                    _pd: Default::default(),
379                }
380            }
381        }
382
383        /// Copies data from a [main read buffer](ReadDevices) into the [main write buffer](WriteDevices) for specified devices
384        ///
385        /// # Examples
386        ///
387        /// ```rust
388        /// use voicemeeter::{interface::callback::BufferMainData, types::Device};
389        /// # fn example(buffer: &mut BufferMainData) {
390        /// buffer
391        ///     .write
392        ///     .copy_device_from(&buffer.read, &[Device::OutputA1, Device::OutputA2]);
393        ///
394        /// assert!(
395        ///     buffer.read.output_a1.to_slice() == buffer.write.output_a1.to_mut_slice(),
396        ///     "strip1 was copied"
397        /// );
398        /// assert!(
399        ///     buffer.read.output_a2.to_slice() == buffer.write.output_a2.to_mut_slice(),
400        ///     "strip2 was copied"
401        /// );
402        /// # }
403        /// ```
404        pub fn copy_device_from<'i>(
405            &mut self,
406            read: &ReadDevices<'_, '_>,
407            devices: impl IntoIterator<Item = &'i Device>,
408        ) {
409            for device in devices {
410                let DeviceBuffer::Buffer(write) = self.device_mut(device) else {
411                    continue;
412                };
413                let DeviceBuffer::Buffer(read) = read.device(device) else {
414                    continue;
415                };
416                assert_eq!(read.len(), write.len());
417                for (read, write) in read.iter().zip(write.iter_mut()) {
418                    write.copy_from_slice(read)
419                }
420            }
421        }
422
423        /// Grab the device buffer for a specific device
424        pub fn device_mut(&mut self, device: &Device) -> DeviceBuffer<&mut [&'b mut [f32]]> {
425            match device {
426                Device::OutputA1 => self.output_a1.as_mut_slice(),
427                Device::OutputA2 => self.output_a2.as_mut_slice(),
428                Device::OutputA3 => self.output_a3.as_mut_slice(),
429                Device::OutputA4 => self.output_a4.as_mut_slice(),
430                Device::OutputA5 => self.output_a5.as_mut_slice(),
431                Device::VirtualOutputB1 => self.virtual_output_b1.as_mut_slice(),
432                Device::VirtualOutputB2 => self.virtual_output_b2.as_mut_slice(),
433                Device::VirtualOutputB3 => self.virtual_output_b3.as_mut_slice(),
434                _ => DeviceBuffer::None,
435            }
436        }
437    }
438}
439
440/// Output mode
441pub mod output {
442    use super::*;
443
444    /// Read interface for output mode
445    #[derive(Default)]
446    pub struct ReadDevices<'a, 'b> {
447        /// Channel read buffer for [`OutputA1`](Device::OutputA1).
448        ///
449        /// Is [`None`](DeviceBuffer::None) if the device is not available.
450        pub output_a1: DeviceBuffer<[&'b [f32]; 8]>,
451        /// Channel read buffer for [`OutputA2`](Device::OutputA2).
452        ///
453        /// Is [`None`](DeviceBuffer::None) if the device is not available.
454        pub output_a2: DeviceBuffer<[&'b [f32]; 8]>,
455        /// Channel read buffer for [`OutputA3`](Device::OutputA3).
456        ///
457        /// Is [`None`](DeviceBuffer::None) if the device is not available.
458        pub output_a3: DeviceBuffer<[&'b [f32]; 8]>,
459        /// Channel read buffer for [`OutputA4`](Device::OutputA4).
460        ///
461        /// Is [`None`](DeviceBuffer::None) if the device is not available.
462        pub output_a4: DeviceBuffer<[&'b [f32]; 8]>,
463        /// Channel read buffer for [`OutputA5`](Device::OutputA5).
464        ///
465        /// Is [`None`](DeviceBuffer::None) if the device is not available.
466        pub output_a5: DeviceBuffer<[&'b [f32]; 8]>,
467        /// Channel read buffer for [`VirtualOutputB1`](Device::VirtualOutputB1).
468        ///
469        /// Is [`None`](DeviceBuffer::None) if the device is not available.
470        pub virtual_output_b1: DeviceBuffer<[&'b [f32]; 8]>,
471        /// Channel read buffer for [`VirtualOutputB2`](Device::VirtualOutputB2).
472        ///
473        /// Is [`None`](DeviceBuffer::None) if the device is not available.
474        pub virtual_output_b2: DeviceBuffer<[&'b [f32]; 8]>,
475        /// Channel read buffer for [`VirtualOutputB3`](Device::VirtualOutputB3).
476        ///
477        /// Is [`None`](DeviceBuffer::None) if the device is not available.
478        pub virtual_output_b3: DeviceBuffer<[&'b [f32]; 8]>,
479        _pd: std::marker::PhantomData<&'a ()>,
480    }
481    impl<'a, 'b> ReadDevices<'a, 'b> {
482        /// Create a new buffer for this mode
483        pub(crate) unsafe fn new(buffer: &'_ mut Output) -> Self {
484            unsafe {
485                Self {
486                    output_a1: buffer.device_read(&Device::OutputA1),
487                    output_a2: buffer.device_read(&Device::OutputA2),
488                    output_a3: buffer.device_read(&Device::OutputA3),
489                    output_a4: buffer.device_read(&Device::OutputA4),
490                    output_a5: buffer.device_read(&Device::OutputA5),
491                    virtual_output_b1: buffer.device_read(&Device::VirtualOutputB1),
492                    virtual_output_b2: buffer.device_read(&Device::VirtualOutputB2),
493                    virtual_output_b3: buffer.device_read(&Device::VirtualOutputB3),
494                    _pd: Default::default(),
495                }
496            }
497        }
498        /// Grab the device buffer for a specific device
499        pub fn device(&'a self, device: &Device) -> DeviceBuffer<&'a [&'b [f32]]> {
500            match device {
501                Device::OutputA1 => self.output_a1.as_slice(),
502                Device::OutputA2 => self.output_a2.as_slice(),
503                Device::OutputA3 => self.output_a3.as_slice(),
504                Device::OutputA4 => self.output_a4.as_slice(),
505                Device::OutputA5 => self.output_a5.as_slice(),
506                Device::VirtualOutputB1 => self.virtual_output_b1.as_slice(),
507                Device::VirtualOutputB2 => self.virtual_output_b2.as_slice(),
508                Device::VirtualOutputB3 => self.virtual_output_b3.as_slice(),
509                _ => DeviceBuffer::None,
510            }
511        }
512    }
513
514    /// Write interface for output mode
515    #[derive(Default)]
516    pub struct WriteDevices<'a, 'b> {
517        /// Channel write buffer for [`OutputA1`](Device::OutputA1).
518        ///
519        /// Is [`None`](DeviceBuffer::None) if the device is not available.
520        pub output_a1: DeviceBuffer<[&'b mut [f32]; 8]>,
521        /// Channel write buffer for [`OutputA2`](Device::OutputA2).
522        ///
523        /// Is [`None`](DeviceBuffer::None) if the device is not available.
524        pub output_a2: DeviceBuffer<[&'b mut [f32]; 8]>,
525        /// Channel write buffer for [`OutputA3`](Device::OutputA3).
526        ///
527        /// Is [`None`](DeviceBuffer::None) if the device is not available.
528        pub output_a3: DeviceBuffer<[&'b mut [f32]; 8]>,
529        /// Channel write buffer for [`OutputA4`](Device::OutputA4).
530        ///
531        /// Is [`None`](DeviceBuffer::None) if the device is not available.
532        pub output_a4: DeviceBuffer<[&'b mut [f32]; 8]>,
533        /// Channel write buffer for [`OutputA5`](Device::OutputA5).
534        ///
535        /// Is [`None`](DeviceBuffer::None) if the device is not available.
536        pub output_a5: DeviceBuffer<[&'b mut [f32]; 8]>,
537        /// Channel write buffer for [`VirtualOutputB1`](Device::VirtualOutputB1).
538        ///
539        /// Is [`None`](DeviceBuffer::None) if the device is not available.
540        pub virtual_output_b1: DeviceBuffer<[&'b mut [f32]; 8]>,
541        /// Channel write buffer for [`VirtualOutputB2`](Device::VirtualOutputB2).
542        ///
543        /// Is [`None`](DeviceBuffer::None) if the device is not available.
544        pub virtual_output_b2: DeviceBuffer<[&'b mut [f32]; 8]>,
545        /// Channel write buffer for [`VirtualOutputB3`](Device::VirtualOutputB3).
546        ///
547        /// Is [`None`](DeviceBuffer::None) if the device is not available.
548        pub virtual_output_b3: DeviceBuffer<[&'b mut [f32]; 8]>,
549        _pd: std::marker::PhantomData<&'a ()>,
550    }
551    impl<'a, 'b> WriteDevices<'a, 'b> {
552        /// Create a new buffer for this mode
553        pub(crate) unsafe fn new(buffer: &'_ mut Output) -> Self {
554            unsafe {
555                Self {
556                    output_a1: buffer.device_write(&Device::OutputA1),
557                    output_a2: buffer.device_write(&Device::OutputA2),
558                    output_a3: buffer.device_write(&Device::OutputA3),
559                    output_a4: buffer.device_write(&Device::OutputA4),
560                    output_a5: buffer.device_write(&Device::OutputA5),
561                    virtual_output_b1: buffer.device_write(&Device::VirtualOutputB1),
562                    virtual_output_b2: buffer.device_write(&Device::VirtualOutputB2),
563                    virtual_output_b3: buffer.device_write(&Device::VirtualOutputB3),
564                    _pd: Default::default(),
565                }
566            }
567        }
568
569        /// Copies data from a [output read buffer](ReadDevices) into the [output write buffer](WriteDevices) for specified devices
570        ///
571        /// # Examples
572        ///
573        /// ```rust
574        /// use voicemeeter::{interface::callback::BufferInData, types::Device};
575        /// # fn example(buffer: &mut BufferInData) {
576        /// buffer
577        ///     .write
578        ///     .copy_device_from(&buffer.read, &[Device::Strip1, Device::Strip2]);
579        ///
580        /// assert!(
581        ///     buffer.read.strip1.to_slice() == buffer.write.strip1.to_mut_slice(),
582        ///     "strip1 was copied"
583        /// );
584        /// assert!(
585        ///     buffer.read.strip2.to_slice() == buffer.write.strip2.to_mut_slice(),
586        ///     "strip2 was copied"
587        /// );
588        /// # }
589        /// ```
590        pub fn copy_device_from<'i>(
591            &mut self,
592            read: &ReadDevices<'_, '_>,
593            devices: impl IntoIterator<Item = &'i Device>,
594        ) {
595            for device in devices {
596                let DeviceBuffer::Buffer(write) = self.device_mut(device) else {
597                    continue;
598                };
599                let DeviceBuffer::Buffer(read) = read.device(device) else {
600                    continue;
601                };
602                assert_eq!(read.len(), write.len());
603                for (read, write) in read.iter().zip(write.iter_mut()) {
604                    write.copy_from_slice(read)
605                }
606            }
607        }
608        /// Grab the device buffer for a specific device
609        pub fn device_mut(&mut self, device: &Device) -> DeviceBuffer<&mut [&'b mut [f32]]> {
610            match device {
611                Device::OutputA1 => self.output_a1.as_mut_slice(),
612                Device::OutputA2 => self.output_a2.as_mut_slice(),
613                Device::OutputA3 => self.output_a3.as_mut_slice(),
614                Device::OutputA4 => self.output_a4.as_mut_slice(),
615                Device::OutputA5 => self.output_a5.as_mut_slice(),
616                Device::VirtualOutputB1 => self.virtual_output_b1.as_mut_slice(),
617                Device::VirtualOutputB2 => self.virtual_output_b2.as_mut_slice(),
618                Device::VirtualOutputB3 => self.virtual_output_b3.as_mut_slice(),
619                _ => DeviceBuffer::None,
620            }
621        }
622    }
623}
624
625/// Input mode
626pub mod input {
627    use super::*;
628
629    /// Read interface for input mode
630    #[derive(Default)]
631    pub struct ReadDevices<'a, 'b> {
632        /// Channel read buffer for [`Strip1`](Device::Strip1).
633        ///
634        /// Is [`None`](DeviceBuffer::None) if the device is not available.
635        pub strip1: DeviceBuffer<[&'b [f32]; 2]>,
636        /// Channel read buffer for [`Strip2`](Device::Strip2).
637        ///
638        /// Is [`None`](DeviceBuffer::None) if the device is not available.
639        pub strip2: DeviceBuffer<[&'b [f32]; 2]>,
640        /// Channel read buffer for [`Strip3`](Device::Strip3).
641        ///
642        /// Is [`None`](DeviceBuffer::None) if the device is not available.
643        pub strip3: DeviceBuffer<[&'b [f32]; 2]>,
644        /// Channel read buffer for [`Strip4`](Device::Strip4).
645        ///
646        /// Is [`None`](DeviceBuffer::None) if the device is not available.
647        pub strip4: DeviceBuffer<[&'b [f32]; 2]>,
648        /// Channel read buffer for [`Strip5`](Device::Strip5).
649        ///
650        /// Is [`None`](DeviceBuffer::None) if the device is not available.
651        pub strip5: DeviceBuffer<[&'b [f32]; 2]>,
652        /// Channel read buffer for [`VirtualInput`](Device::VirtualInput).
653        ///
654        /// Is [`None`](DeviceBuffer::None) if the device is not available.
655        pub virtual_input: DeviceBuffer<[&'b [f32]; 8]>,
656        /// Channel read buffer for [`VirtualInputAux`](Device::VirtualInputAux).
657        ///
658        /// Is [`None`](DeviceBuffer::None) if the device is not available.
659        pub virtual_input_aux: DeviceBuffer<[&'b [f32]; 8]>,
660        /// Channel read buffer for [`VirtualInput8`](Device::VirtualInput8).
661        ///
662        /// Is [`None`](DeviceBuffer::None) if the device is not available.
663        pub virtual_input8: DeviceBuffer<[&'b [f32]; 8]>,
664        _pd: std::marker::PhantomData<&'a ()>,
665    }
666    impl<'a, 'b> ReadDevices<'a, 'b> {
667        /// Create a new buffer for this mode
668        pub(crate) unsafe fn new(buffer: &'_ mut Input) -> Self {
669            unsafe {
670                Self {
671                    strip1: buffer.device_read(&Device::Strip1),
672                    strip2: buffer.device_read(&Device::Strip2),
673                    strip3: buffer.device_read(&Device::Strip3),
674                    strip4: buffer.device_read(&Device::Strip4),
675                    strip5: buffer.device_read(&Device::Strip5),
676                    virtual_input: buffer.device_read(&Device::VirtualInput),
677                    virtual_input_aux: buffer.device_read(&Device::VirtualInputAux),
678                    virtual_input8: buffer.device_read(&Device::VirtualInput8),
679                    _pd: Default::default(),
680                }
681            }
682        }
683
684        /// Grab the device buffer for a specific device
685        pub fn device(&'a self, device: &Device) -> DeviceBuffer<&'a [&'b [f32]]> {
686            match device {
687                Device::Strip1 => self.strip1.as_slice(),
688                Device::Strip2 => self.strip2.as_slice(),
689                Device::Strip3 => self.strip3.as_slice(),
690                Device::Strip4 => self.strip4.as_slice(),
691                Device::Strip5 => self.strip5.as_slice(),
692                Device::VirtualInput => self.virtual_input.as_slice(),
693                Device::VirtualInputAux => self.virtual_input_aux.as_slice(),
694                Device::VirtualInput8 => self.virtual_input8.as_slice(),
695                _ => DeviceBuffer::None,
696            }
697        }
698    }
699
700    /// Write interface for input mode
701    #[derive(Default)]
702    pub struct WriteDevices<'a, 'b> {
703        /// Channel write buffer for [`Strip1`](Device::Strip1).
704        ///
705        /// Is [`None`](DeviceBuffer::None) if the device is not available.
706        pub strip1: DeviceBuffer<[&'b mut [f32]; 2]>,
707        /// Channel write buffer for [`Strip2`](Device::Strip2).
708        ///
709        /// Is [`None`](DeviceBuffer::None) if the device is not available.
710        pub strip2: DeviceBuffer<[&'b mut [f32]; 2]>,
711        /// Channel write buffer for [`Strip3`](Device::Strip3).
712        ///
713        /// Is [`None`](DeviceBuffer::None) if the device is not available.
714        pub strip3: DeviceBuffer<[&'b mut [f32]; 2]>,
715        /// Channel write buffer for [`Strip4`](Device::Strip4).
716        ///
717        /// Is [`None`](DeviceBuffer::None) if the device is not available.
718        pub strip4: DeviceBuffer<[&'b mut [f32]; 2]>,
719        /// Channel write buffer for [`Strip5`](Device::Strip5).
720        ///
721        /// Is [`None`](DeviceBuffer::None) if the device is not available.
722        pub strip5: DeviceBuffer<[&'b mut [f32]; 2]>,
723        /// Channel write buffer for [`VirtualInput`](Device::VirtualInput).
724        ///
725        /// Is [`None`](DeviceBuffer::None) if the device is not available.
726        pub virtual_input: DeviceBuffer<[&'b mut [f32]; 8]>,
727        /// Channel write buffer for [`VirtualInputAux`](Device::VirtualInputAux).
728        ///
729        /// Is [`None`](DeviceBuffer::None) if the device is not available.
730        pub virtual_input_aux: DeviceBuffer<[&'b mut [f32]; 8]>,
731        /// Channel write buffer for [`VirtualInput8`](Device::VirtualInput8).
732        ///
733        /// Is [`None`](DeviceBuffer::None) if the device is not available.
734        pub virtual_input8: DeviceBuffer<[&'b mut [f32]; 8]>,
735        _pd: std::marker::PhantomData<&'a ()>,
736    }
737    impl<'a, 'b> WriteDevices<'a, 'b> {
738        /// Create a new buffer for this mode
739        pub(crate) unsafe fn new(buffer: &'_ mut Input) -> Self {
740            unsafe {
741                Self {
742                    strip1: buffer.device_write(&Device::Strip1),
743                    strip2: buffer.device_write(&Device::Strip2),
744                    strip3: buffer.device_write(&Device::Strip3),
745                    strip4: buffer.device_write(&Device::Strip4),
746                    strip5: buffer.device_write(&Device::Strip5),
747                    virtual_input: buffer.device_write(&Device::VirtualInput),
748                    virtual_input_aux: buffer.device_write(&Device::VirtualInputAux),
749                    virtual_input8: buffer.device_write(&Device::VirtualInput8),
750                    _pd: Default::default(),
751                }
752            }
753        }
754
755        /// Copies data from a [input read buffer](ReadDevices) into the [input write buffer](WriteDevices) for specified devices
756        ///
757        /// # Examples
758        ///
759        /// ```rust
760        /// use voicemeeter::{interface::callback::BufferInData, types::Device};
761        /// # fn example(buffer: &mut BufferInData) {
762        /// buffer
763        ///     .write
764        ///     .copy_device_from(&buffer.read, &[Device::Strip1, Device::Strip2]);
765        ///
766        /// assert!(
767        ///     buffer.read.strip1.to_slice() == buffer.write.strip1.to_mut_slice(),
768        ///     "strip1 was copied"
769        /// );
770        /// assert!(
771        ///     buffer.read.strip2.to_slice() == buffer.write.strip2.to_mut_slice(),
772        ///     "strip2 was copied"
773        /// );
774        /// # }
775        /// ```
776        pub fn copy_device_from<'i>(
777            &mut self,
778            read: &ReadDevices<'_, '_>,
779            devices: impl IntoIterator<Item = &'i Device>,
780        ) {
781            for device in devices {
782                let DeviceBuffer::Buffer(write) = self.device_mut(device) else {
783                    continue;
784                };
785                let DeviceBuffer::Buffer(read) = read.device(device) else {
786                    continue;
787                };
788                assert_eq!(read.len(), write.len());
789                for (read, write) in read.iter().zip(write.iter_mut()) {
790                    write.copy_from_slice(read)
791                }
792            }
793        }
794        /// Grab the device buffer for a specific device
795        pub fn device_mut(&mut self, device: &Device) -> DeviceBuffer<&mut [&'b mut [f32]]> {
796            match device {
797                Device::Strip1 => self.strip1.as_mut_slice(),
798                Device::Strip2 => self.strip2.as_mut_slice(),
799                Device::Strip3 => self.strip3.as_mut_slice(),
800                Device::Strip4 => self.strip4.as_mut_slice(),
801                Device::Strip5 => self.strip5.as_mut_slice(),
802                Device::VirtualInput => self.virtual_input.as_mut_slice(),
803                Device::VirtualInputAux => self.virtual_input_aux.as_mut_slice(),
804                Device::VirtualInput8 => self.virtual_input8.as_mut_slice(),
805                _ => DeviceBuffer::None,
806            }
807        }
808    }
809}